#include<iostream>
#include<sys/wait.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<assert.h>

using namespace std;

/*
 为什么exec系列的函数都没有返回值呢，为什么只有错误的时候有返回值-1呢？
 这是因为exec系列函数的执行都是把原来的代码替换出去，一旦执行成功了，就只会执行该函数，其他的都被替换出去了
 也就是exec系列函数只要有返回值，那么一定是exec系列函数出错了
 */

void execl_test()
{
    sleep(1);
    execl("/usr/bin/ls","ls","-l","-i","-a","--color=auto",NULL);
    /*
    我们发现，在我们执行玩execl()后，cout并没用执行，这是为什么呢？
    这是因为cout、endl也是函数，并且都在execl()之后
    execl()之后完成之后，代码已经被全部覆盖了，就是被替换出去了，开始执行新的代码了，所以cout、endl就不会再被执行了！
    */
    cout << "process running done...." << endl;
    //当我们写了一个无法被执行的命令时，execl()就会失败，就无法执行替换，会跳过execl()，继续执行原来的代码
    execl("/usr/bin/lsadadadadaf","ls","-l","-i","-a","--color=auto",NULL);
    perror("execl");

}

void execlp_test()
{
    execlp("ls","ls","-l","-i","-a","--color=auto",NULL);
}

void execv_test()
{
    /*
     复习一下const在*下的三种情况
     1.const int* a = &b;
     2.int const* a = &b;
     3.int *const a = &b;
     这三种情况中 1的效果是和2相同的，
     也就是说const在*左边的时候，则指针指向的变量的值是不可直接通过指针更改的(但可通过其它方式进行更改)
     const在*右边的时候，则指针的指向是不可进行更改的。
     也就是左定值，右定向。
     */
    char* const argv_[] = {
        "ls",
        "-l",
        "-i",
        "-a",
        "--color=auto",
        NULL 
    };
    execv("/usr/bin/ls",argv_);
}

void execvp_test()
{

    char* const argv_[] = {
        "ls",
        "-l",
        "-i",
        "-a",
        "--color=auto",
        NULL 
    };
    execvp("ls",argv_);
}


//进程程序间的替换
void Program_substitution()
{
    //也就是实现该路径下的文件替换
    execl("./test1","test1",NULL);
}

void myenv_test()
{
    //cout << "PATH:" << " " << getenv("PATH") << endl;
    //cout << "HOME:" << " " << getenv("HOME") << endl;
    //cout << "PWD:" << " " << getenv("PWD") << endl;
    //cout << "MYENV:" << " " << getenv("MYENV") << endl;
    
    
    ////自己定义属于自己的环境变量
    char *const myenv_[] = {
       (char*)"MYENV=123456789",
       NULL 
    };

    //需要自己定义environ，要不然编译不过.
    extern char **environ;
    putenv((char*)"MYENV=123456789");//自己手动put自己定义的环境变量
    //execl("./test1","test1",NULL,myenv_);
    execl("./test1","test1",NULL,environ);//environ默认传入的是系统环境变量
}


int main()
{
    //execvp_test();
    //Program_substitution();
    myenv_test();
    return 0;
}
